/********************************************************************
 * @file     arw97420.c
 * @brief    arw97420芯片的stm32平台驱动库实现
 *
 * @author   lzy (lllzzzyyy@buaa.edu.cn)
 * @url      https://sinlatansen.site
 *
 * @date     2025-02-14
 *
 *   █████╗ ██████╗ ██╗    ██╗ █████╗ ███████╗██╗  ██╗██████╗  ██████╗
 *  ██╔══██╗██╔══██╗██║    ██║██╔══██╗╚════██║██║  ██║╚════██╗██╔═████╗
 *  ███████║██████╔╝██║ █╗ ██║╚██████║    ██╔╝███████║ █████╔╝██║██╔██║
 *  ██╔══██║██╔══██╗██║███╗██║ ╚═══██║   ██╔╝ ╚════██║██╔═══╝ ████╔╝██║
 *  ██║  ██║██║  ██║╚███╔███╔╝ █████╔╝   ██║       ██║███████╗╚██████╔╝
 *  ╚═╝  ╚═╝╚═╝  ╚═╝ ╚══╝╚══╝  ╚════╝    ╚═╝       ╚═╝╚══════╝ ╚═════╝
 *
 ********************************************************************/

#include "arw97420.h"

#include <malloc.h>
#include <string.h>

#include "binary_to_hex.h"

/* 指针判空 */
#define ARW_CHECK_NULLPTR(ptr)               \
    do {                                     \
        if (NULL == (ptr)) {                 \
            this->err_code = kArwErrNullPtr; \
            return 1;                        \
        }                                    \
    } while (0)

/* 写引脚 */
#define ARW_WRITE_PIN(pin_name, state)                                                           \
    HAL_GPIO_WritePin(this->hardware.pin_name##_pin.port_ptr, this->hardware.pin_name##_pin.pin, \
                      state ? GPIO_PIN_SET : GPIO_PIN_RESET)

/* 读引脚 */
#define ARW_READ_PIN(pin_name) \
    HAL_GPIO_ReadPin(this->hardware.pin_name##_pin.port_ptr, this->hardware.pin_name##_pin.pin)

/* 时间 */
#define ARW_DELAY_HALF_CLK(n) ARW_DELAY_NS(500 / ARW_SPI_SPEED_MHZ * (n)) /**< 延时 n 个 半周期 */

#define ARW_DELAY_E_FUSE() ARW_DELAY_US(3)

#define ARW_DELAY_TCS_LAG() ARW_DELAY_NS(22)
#define ARW_DELAY_TCS_LEAD() ARW_DELAY_HALF_CLK(2)
#define ARW_DELAY_TCS_S() ARW_DELAY_NS(12)
#define ARW_DELAY_TCS_H() ARW_DELAY_NS(22)
#define ARW_DELAY_TCS_TRIG() ARW_DELAY_HALF_CLK(4)
#define ARW_DELAY_TCS_DE() ARW_DELAY_HALF_CLK(4)

#define ARW_DELAY_TDATA_SU() ARW_DELAY_NS(12)
#define ARW_DELAY_TDATA_H() ARW_DELAY_NS(12)

#define ARW_DELAY_TLD_SU() ARW_DELAY_HALF_CLK(2)
#define ARW_DELAY_TLD_H() ARW_DELAY_HALF_CLK(2)

#define ARW_DELAY_TRR() ARW_DELAY_NS(200)

/* 翻转n个时钟周期 */
#define ARW_CLK_FLIP(n)                 \
    do {                                \
        for (int i = 0; i < (n); i++) { \
            ARW_WRITE_PIN(clki, 1);     \
            ARW_DELAY_HALF_CLK(1);      \
            ARW_WRITE_PIN(clki, 0);     \
            ARW_DELAY_HALF_CLK(1);      \
        }                               \
    } while (0)

/* 寄存器地址 */
#define ARW_ADDR_TEMP 0x02  /**< 温度寄存器, 通过SPI_SHORT配置 */
#define ARW_ADDR_RESET 0x03 /**< 复位寄存器, 通过SPI_SHORT配置 */
#define ARW_ADDR_RF 0x40    /**< RF寄存器, 通过SPI_LONG和BFC配置 */

/**
 *  @brief CMDTYPE
 *  @details
 *    Bit[7:2]: 固定为101010，也就是0x2A
 *    Bit[1:0](CMD[1:0]): 对应CMD.TYPE码值，
 *    Short Frame为00，Long Frame为01
 */
#define ARW_ADDR_CMDTYPE_LONG_TO_SHORT 0xA8
#define ARW_ADDR_CMDTYPE_SHORT_TO_LONG 0xA9

#define NUM_OF_INIT_COMMANDS 16 /**< 初始化命令个数 */

/**
 * @enum ArwSpiOp
 * @brief SPI操作类型
 * @details
 *           OP=1时, CMD.TYPE
 *           OP=0时, :
 *              SHORT: 温度, RESET
 *              LONG : RF
 */
typedef enum ArwSpiOp {
    kArwSpiOpRfTempReset = 0,
    kArwSpiOpCmdType = 1,
} ArwSpiOp_t;

/**
 * @enum ArwSpiRW
 * @brief SPI读写模式
 */
typedef enum ArwSpiRW {
    kArwSpiWrite = 0, /**< 写寄存器 */
    kArwSpiRead = 1   /**< 读寄存器 */
} ArwSpiRW_t;

/**
 * @struct ArwSpiConfig
 * @brief SPI协议配置
 */
typedef struct ArwSpiConfig {
    ArwSpiRW_t rw; /**< 读写模式 */
    ArwSpiOp_t op; /**< 操作类型 */
    uint8_t addr;  /**< 寄存器地址 */
} ArwSpiConfig_t;

/**
 * @brief SPI协议发送字节流
 */
static uint8_t ArwSendBits(ArwHandle_t* this, uint8_t* bit_ptr, uint8_t bit_count) {
    ARW_CHECK_NULLPTR(bit_ptr);
    for (int i = 0; i < bit_count; i++) {
        uint8_t bit = ((bit_ptr[i / 8]) >> (7 - (i % 8))) & B00000001;
        ARW_WRITE_PIN(sdi, bit);
        ARW_WRITE_PIN(clki, 1);
        ARW_DELAY_HALF_CLK(1);

        if (i == bit_count - 1) {
            break;
        }
        ARW_WRITE_PIN(clki, 0);
        ARW_DELAY_HALF_CLK(1);
    }
    return 0;
}

/**
 * @brief SPI协议接收字节流
 */
static uint8_t ArwRecvBits(ArwHandle_t* this, uint8_t* bit_ptr, uint8_t bit_count) {
    ARW_CHECK_NULLPTR(bit_ptr);
    memset(bit_ptr, 0, (bit_count / 8) + 1);
    for (int i = 0; i < bit_count; i++) {
        ARW_WRITE_PIN(clki, 1);
        uint8_t bit = ARW_READ_PIN(sdo);
        bit_ptr[i / 8] |= (bit << (7 - i % 8));
        ARW_DELAY_HALF_CLK(1);

        if (i == bit_count - 1) {
            break;
        }
        ARW_WRITE_PIN(clki, 0);
        ARW_DELAY_HALF_CLK(1);
    }
    return 0;
}

/**
 * @brief SPI协议获取帧头
 * @details
 *           -----------------------
 *             Bits    Description
 *           -----------------------
 *             [11]      Mode: 0
 *             [10]      Mode: 1
 *              [9]        R/W
 *              [8]        OP
 *             [7:0]     Address
 *           -----------------------
 */
static uint16_t ArwSpiGetHeader(ArwSpiConfig_t* cfg_ptr) {
    uint16_t header = 0;

    header |= (0x01 << 10);
    header |= (cfg_ptr->rw << 9);
    header |= (cfg_ptr->op << 8);
    header |= cfg_ptr->addr;

    return (header << 4);
}

/**
 * @brief SPI协议尾部操作
 */
static void ArwSpiTail(ArwHandle_t* this) {
    ARW_DELAY_TCS_LAG();
    ARW_WRITE_PIN(cs, 1);
    ARW_DELAY_TCS_S();
    ARW_WRITE_PIN(clki, 0);
    ARW_DELAY_HALF_CLK(1);
    ARW_CLK_FLIP(4);
    ARW_DELAY_TCS_H();
    ARW_WRITE_PIN(cs, 0);
    ARW_DELAY_TCS_TRIG();
    ARW_WRITE_PIN(cs, 1);
    ARW_DELAY_TCS_DE();
}

/**
 * @brief SPI协议SDI帧
 */
static uint8_t ArwSpiSdiFrame(ArwHandle_t* this, ArwSpiConfig_t* cfg_ptr, uint8_t* data_ptr, uint8_t data_size) {
    ARW_CHECK_NULLPTR(cfg_ptr);
    ARW_CHECK_NULLPTR(data_ptr);

    ARW_WRITE_PIN(cs, 0);
    ARW_DELAY_TCS_LEAD();

    //* 获得帧头
    uint16_t header = ArwSpiGetHeader(cfg_ptr);
    uint8_t header_bytes[2] = {
        (header >> 8) & B11111111,
        header & B11111111,
    };

    //* 发送帧头
    if (ArwSendBits(this, header_bytes, ARW_SPI_HEADER_COUNT)) {
        return 1;
    }

    //* 发送data
    if (ARW_CONFIG_DATA_SIZE == data_size) {
        uint8_t dummy_data = 0;
        if (ArwSendBits(this, &dummy_data, ARW_SPI_CONTROL_COUNT)) {
            return 1;
        }
    }
    if (ArwSendBits(this, data_ptr, data_size * 8)) {
        return 1;
    }

    //* 尾部操作
    ArwSpiTail(this);
    return 0;
}

/**
 * @brief SPI协议SDO帧
 */
static uint8_t ArwSpiSdoFrame(ArwHandle_t* this, ArwSpiConfig_t* cfg_ptr, uint8_t* data_ptr, uint8_t data_size) {
    ARW_CHECK_NULLPTR(cfg_ptr);
    ARW_CHECK_NULLPTR(data_ptr);

    //* 1. 拉低cs
    ARW_WRITE_PIN(cs, 0);
    ARW_DELAY_TCS_LEAD();

    if (kArwSpiWrite == cfg_ptr->rw) {
        //* 2. 读帧头
        uint8_t received_header_bytes[2];
        if (ArwRecvBits(this, received_header_bytes, ARW_SPI_HEADER_COUNT)) {
            return 1;
        }

        //* 3. 比较帧头
        uint16_t expected_header = ArwSpiGetHeader(cfg_ptr);
        uint16_t received_header = (uint16_t)(received_header_bytes[0] << 8 | received_header_bytes[1]);
        if (expected_header != received_header) {
            goto error;
        }
    }

    //* 4. long, 丢弃前2位
    if (ARW_CONFIG_DATA_SIZE == data_size) {
        uint8_t dummy_data;
        if (ArwRecvBits(this, &dummy_data, ARW_SPI_CONTROL_COUNT)) {
            return 1;
        }
    }

    //* 5. 读data
    if (ArwRecvBits(this, data_ptr, data_size * 8)) {
        return 1;
    }

    //* 6. 尾部操作
    ArwSpiTail(this);
    return 0;

error:
    ARW_WRITE_PIN(cs, 1);
    return 1;
}

/**
 * @brief BFC发送
 * @details
 *           -------------------------------
 *               Bits          Description
 *           -------------------------------
 *             [105:104]         Control
 *             [103:78]            CH4
 *              [77:52]            CH3
 *              [51:26]            CH2
 *              [25:0]             CH1
 *           -------------------------------
 */
static uint8_t ArwBfcTransmit(ArwHandle_t* this, uint8_t* data_ptr, uint8_t data_size) {
    ARW_CHECK_NULLPTR(data_ptr);
    if (ARW_CONFIG_DATA_SIZE != data_size) {
        this->err_code = kArwErrDataSize;
        return 1;
    }
    ARW_ENTER_CRITICAL();

    ARW_WRITE_PIN(ld, 0);
    ARW_WRITE_PIN(cs, 0);
    ARW_DELAY_TCS_LEAD();

    if (ArwSendBits(this, data_ptr, data_size * 8)) {
        return 1;
    }

    ARW_WRITE_PIN(cs, 1);
    ARW_DELAY_TLD_SU();
    ARW_WRITE_PIN(ld, 1);
    ARW_DELAY_TLD_H();
    ARW_WRITE_PIN(ld, 0);

    ARW_EXIT_CRITICAL();
    return 0;
}

/**
 * @brief 短帧收发
 */
static uint8_t ArwSpiShortTransfer(ArwHandle_t* this, ArwSpiConfig_t* cfg_ptr, uint8_t* data_ptr, uint8_t data_size) {
    ARW_CHECK_NULLPTR(cfg_ptr);
    ARW_CHECK_NULLPTR(data_ptr);
    if (ARW_SPI_SHORT_DATA_SIZE != data_size) {
        return 1;
    }
    ARW_ENTER_CRITICAL();

    //* sdi帧
    if (ArwSpiSdiFrame(this, cfg_ptr, data_ptr, data_size)) {
        goto error;
    }

    //* 切帧不读串出
    if (kArwSpiOpCmdType != cfg_ptr->op) {
        uint8_t received_data[ARW_SPI_SHORT_DATA_SIZE];
        if (ArwSpiSdoFrame(this, cfg_ptr, received_data, ARW_SPI_SHORT_DATA_SIZE)) {
            goto error;
        }

        if (kArwSpiWrite == cfg_ptr->rw) {
            //* 写寄存器, 验证串出
            if (memcmp(data_ptr, received_data, ARW_SPI_SHORT_DATA_SIZE)) {
                this->err_code = kArwErrSpiData;
                goto error;
            }
        } else {
            //* 读寄存器, 存入数据
            memcpy(data_ptr, received_data, ARW_SPI_SHORT_DATA_SIZE);
        }
    }

    ARW_EXIT_CRITICAL();
    return 0;

error:
    ARW_EXIT_CRITICAL();
    return 1;
}

/**
 * @brief 长帧仅发送
 */
static uint8_t ArwSpiLongTransmit(ArwHandle_t* this, ArwSpiConfig_t* cfg_ptr, uint8_t* data_ptr, uint8_t data_size) {
    ARW_CHECK_NULLPTR(cfg_ptr);
    ARW_CHECK_NULLPTR(data_ptr);
    if (ARW_CONFIG_DATA_SIZE != data_size) {
        return 1;
    }
    ARW_ENTER_CRITICAL();

    //* sdi帧
    if (ArwSpiSdiFrame(this, cfg_ptr, data_ptr, data_size)) {
        goto error;
    }

    //* 切帧不读串出
    if (kArwSpiOpCmdType != cfg_ptr->op) {
        uint8_t received_data[ARW_CONFIG_DATA_SIZE];
        if (ArwSpiSdoFrame(this, cfg_ptr, received_data, ARW_CONFIG_DATA_SIZE)) {
            goto error;
        }
        //* 比较
        if (memcmp(data_ptr, received_data, ARW_CONFIG_DATA_SIZE)) {
            this->err_code = kArwErrSpiData;
            goto error;
        }
    }

    ARW_EXIT_CRITICAL();
    return 0;

error:
    ARW_EXIT_CRITICAL();
    return 1;
}

/**
 * @brief 发送模式切换命令
 * @details 用于 BFC 和 SPI_Short 互转
 */
static uint8_t ArwSendModeOperation(ArwHandle_t* this) {
    ARW_ENTER_CRITICAL();

    ARW_WRITE_PIN(cs, 0);
    ARW_DELAY_TCS_LEAD();

    ARW_CLK_FLIP(3);

    ARW_DELAY_HALF_CLK(1);
    ARW_WRITE_PIN(clki, 1);
    ARW_DELAY_HALF_CLK(1);

    ARW_DELAY_TCS_H();
    ARW_WRITE_PIN(cs, 1);
    ARW_DELAY_TCS_S();
    ARW_WRITE_PIN(clki, 0);
    ARW_DELAY_HALF_CLK(1);

    ARW_CLK_FLIP(3);
    ARW_WRITE_PIN(clki, 1);
    ARW_DELAY_TCS_H();
    ARW_WRITE_PIN(cs, 0);
    ARW_DELAY_TCS_TRIG();
    ARW_WRITE_PIN(cs, 1);
    ARW_DELAY_TCS_S();

    ARW_EXIT_CRITICAL();
    return 0;
}

/**
 * @brief 短帧转长帧
 */
static uint8_t ArwSpiShortToLong(ArwHandle_t* this) {
    uint8_t dummy_data[ARW_SPI_SHORT_DATA_SIZE] = {0};
    return ArwSpiShortTransfer(
        this, &((ArwSpiConfig_t){.rw = kArwSpiWrite, .op = kArwSpiOpCmdType, .addr = ARW_ADDR_CMDTYPE_SHORT_TO_LONG}),
        dummy_data, ARW_SPI_SHORT_DATA_SIZE);
}

/**
 * @brief 长帧转短帧
 */
static uint8_t ArwSpiLongToShort(ArwHandle_t* this) {
    uint8_t dummy_data[ARW_CONFIG_DATA_SIZE] = {0};
    return ArwSpiLongTransmit(
        this, &((ArwSpiConfig_t){.rw = kArwSpiWrite, .op = kArwSpiOpCmdType, .addr = ARW_ADDR_CMDTYPE_LONG_TO_SHORT}),
        dummy_data, ARW_CONFIG_DATA_SIZE);
}

/**
 * @brief 解析芯片模式
 */
static uint8_t ArwAnalysisChipMode(ArwHandle_t* this, uint8_t* config_ptr, ChipMode_t* chip_mode_ptr) {
    ARW_CHECK_NULLPTR(chip_mode_ptr);

    uint8_t is_tx = config_ptr[0] & B10000000;
    uint8_t is_rx = config_ptr[3] & B01000000;

    if (is_rx && is_tx) {
        this->err_code = kArwErrChipMode;
        return 1;
    }
    if (is_tx && !is_rx) {
        *chip_mode_ptr = kArwChipModeTx;
    }
    if (!is_tx && is_rx) {
        *chip_mode_ptr = kArwChipModeRx;
    }
    if (!is_tx && !is_rx) {
        *chip_mode_ptr = kArwChipModeLoad;
    }

    return 0;
}

/**
 * @brief 设置芯片模式
 */
static uint8_t ArwSetChipMode(ArwHandle_t* this, ChipMode_t next_mode) {
    if (next_mode == this->chip_mode) {
        return 1;
    }

    switch (this->chip_mode) {
        case kArwChipModeRx:
        case kArwChipModeLoad:
            if (kArwChipModeTx == next_mode) {
                ARW_ENTER_CRITICAL();
                ARW_WRITE_PIN(trr, 1);
                ARW_DELAY_TRR();
                ARW_WRITE_PIN(trt, 1);
                ARW_EXIT_CRITICAL();
            }
            break;
        case kArwChipModeTx:
            ARW_ENTER_CRITICAL();
            ARW_WRITE_PIN(trt, 0);
            ARW_DELAY_TRR();
            ARW_WRITE_PIN(trr, 0);
            ARW_EXIT_CRITICAL();
            break;
        default:
            break;
    }

    this->chip_mode = next_mode;
    return 0;
}

/**
 * @brief GPIO初始化
 */
static void ArwGpioInit(GPIO_InitTypeDef* init_ptr, Gpio_t* gpio_ptr) {
    init_ptr->Pin = gpio_ptr->pin;
    HAL_GPIO_Init(gpio_ptr->port_ptr, init_ptr);
}

/**
 * @brief 硬件初始化
 */
static void ArwHardwareInit(ArwHandle_t* this) {
    ArwHardware_t* hw_ptr = &this->hardware;
    ARW_GPIO_CLK_ENABLE();
    GPIO_InitTypeDef gpio_init = {0};
    //* output
    gpio_init.Mode = GPIO_MODE_OUTPUT_PP;
    gpio_init.Pull = GPIO_PULLDOWN;
    gpio_init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    ArwGpioInit(&gpio_init, &hw_ptr->sdi_pin);
    ArwGpioInit(&gpio_init, &hw_ptr->cs_pin);
    ArwGpioInit(&gpio_init, &hw_ptr->ld_pin);
    ArwGpioInit(&gpio_init, &hw_ptr->trt_pin);
    ArwGpioInit(&gpio_init, &hw_ptr->trr_pin);
    ArwGpioInit(&gpio_init, &hw_ptr->clki_pin);
    ArwGpioInit(&gpio_init, &hw_ptr->reset_pin);
    ARW_WRITE_PIN(cs, 1);

    //* input
    gpio_init.Mode = GPIO_MODE_INPUT;
    gpio_init.Pull = GPIO_PULLDOWN;
    ArwGpioInit(&gpio_init, &hw_ptr->sdo_pin);
    ArwGpioInit(&gpio_init, &hw_ptr->clko_pin);
}

/**
 * @brief 初始化命令
 */
static uint8_t ArwInitCommands(ArwHandle_t* this) {
    //* 命令
    static const uint8_t kInitData[NUM_OF_INIT_COMMANDS][2] = {
        {B00100000, B00000000}, {B00000000, B00000000}, {B00000000, B00000000}, {B00000000, B00000000},
        {B00000000, B00000000}, {B10010010, B01000000}, {B00011110, B10000100}, {B10110001, B10001000},
        {B10001000, B10001000}, {B01100000, B00110110}, {B01100000, B01110110}, {B01101110, B11110000},
        {B01111010, B00100000}, {B00000000, B00000000}, {B00000100, B01000000}, {B10010010, B01000000},
    };
    //* 地址
    static const uint8_t kInitAddress[NUM_OF_INIT_COMMANDS] = {
        B00000111, B00001000, B00001001, B00001010, B00001011, B00001100, B00011110, B00011111,
        B00100000, B00100001, B00100010, B00100011, B00100100, B00100101, B00100110, B00100111};

    ARW_ENTER_CRITICAL();
    for (int i = 0; i < NUM_OF_INIT_COMMANDS; i++) {
        if (ArwSpiShortTransfer(
                this, &((ArwSpiConfig_t){.rw = kArwSpiWrite, .op = kArwSpiOpRfTempReset, .addr = kInitAddress[i]}),
                (uint8_t*)kInitData[i], ARW_SPI_SHORT_DATA_SIZE)) {
            ARW_EXIT_CRITICAL();
            return 1;
        }
    }
    return 0;
}

/**
 * @brief 初始化工作流
 */
static uint8_t ArwInitWorkFlow(ArwHandle_t* this) {
    //* GPIO初始化
    ArwHardwareInit(this);

    //* hard reset
    if (ARW97420_HardReset(this)) {
        return 1;
    }

    //* efuse reset
    if (ARW97420_EFuseReset(this)) {
        return 1;
    }

    //* to short
    if (ArwSendModeOperation(this)) {
        return 1;
    }

    //* init commands
    if (ArwInitCommands(this)) {
        return 1;
    }

    return 0;
}

uint8_t ARW97420_HardReset(ArwHandle_t* this) {
    ARW_CHECK_NULLPTR(this);
    ARW_ENTER_CRITICAL();

    ARW_WRITE_PIN(reset, 1);
    ARW_DELAY_US(3);
    ARW_WRITE_PIN(reset, 0);

    ARW_EXIT_CRITICAL();
    return 0;
}

uint8_t ARW97420_EFuseReset(ArwHandle_t* this) {
    ARW_CHECK_NULLPTR(this);
    ARW_ENTER_CRITICAL();

    //* a
    ARW_WRITE_PIN(cs, 0);
    ARW_DELAY_TCS_LEAD();

    ARW_CLK_FLIP(6);
    ARW_DELAY_TCS_LAG();
    ARW_WRITE_PIN(cs, 1);
    ARW_DELAY_TCS_S();

    //* 3us
    ARW_DELAY_E_FUSE();

    //* b
    ARW_WRITE_PIN(cs, 0);
    ARW_DELAY_TCS_LEAD();

    ARW_CLK_FLIP(8);
    ARW_DELAY_TCS_LAG();
    ARW_WRITE_PIN(cs, 1);
    ARW_DELAY_TCS_S();

    ARW_EXIT_CRITICAL();
    return 0;
}

uint8_t ARW97420_SoftReset(ArwHandle_t* this) {
    ARW_CHECK_NULLPTR(this);
    uint8_t dummy_data[ARW_SPI_SHORT_DATA_SIZE] = {1, 1};  // 任意非0值
    return ArwSpiShortTransfer(this,
                               &((ArwSpiConfig_t){
                                   .rw = kArwSpiWrite,
                                   .op = kArwSpiOpCmdType,
                                   .addr = ARW_ADDR_RESET,
                               }),
                               dummy_data, ARW_SPI_SHORT_DATA_SIZE);
}

uint8_t ARW97420_GetTemp(ArwHandle_t* this, float* temp_ptr) {
    ARW_CHECK_NULLPTR(this);
    if (kArwSendModeSpiShort != this->send_mode) {
        this->err_code = kArwErrSendMode;
        return 1;
    }

    uint8_t temp_bytes[ARW_SPI_SHORT_DATA_SIZE] = {0};
    if (ArwSpiShortTransfer(this,
                            &((ArwSpiConfig_t){.rw = kArwSpiRead, .op = kArwSpiOpRfTempReset, .addr = ARW_ADDR_TEMP}),
                            temp_bytes, ARW_SPI_SHORT_DATA_SIZE)) {
        return 1;
    }

    *temp_ptr = (float)temp_bytes[1] * 0.8231F - 74.5F;
    return 0;
}

uint8_t ARW97420_SetRfConfig(ArwHandle_t* this, uint8_t* config_ptr, uint8_t config_size) {
    ARW_CHECK_NULLPTR(this);
    ARW_CHECK_NULLPTR(config_ptr);

    if (ARW_CONFIG_DATA_SIZE != config_size) {
        this->err_code = kArwErrDataSize;
        return 1;
    }
    if (kArwSendModeSpiShort == this->send_mode) {
        this->err_code = kArwErrSendMode;
        return 1;
    }

    //* 解析chipmode, 操作trt, trr
    ChipMode_t next_mode;
    if (ArwAnalysisChipMode(this, config_ptr, &next_mode)) {
        return 1;
    }
    if (ArwSetChipMode(this, next_mode)) {
        return 1;
    }

    //* 发送配置数据, bfc, spi long
    if (kArwSendModeBfc == this->send_mode) {
        if (ArwBfcTransmit(this, config_ptr, config_size)) {
            return 1;
        }
    } else {
        if (ArwSpiLongTransmit(this,
                               &((ArwSpiConfig_t){.rw = kArwSpiWrite, .op = kArwSpiOpRfTempReset, .addr = ARW_ADDR_RF}),
                               config_ptr, config_size)) {
            return 1;
        }
    }
    return 0;
}

uint8_t ARW97420_SetSendMode(ArwHandle_t* this, SendMode_t next_mode) {
    ARW_CHECK_NULLPTR(this);

    if (next_mode > kArwSendModeSpiShort || next_mode == this->send_mode) {
        this->err_code = kArwErrSendMode;
        return 1;
    }

    uint8_t (*op)(ArwHandle_t*) = NULL;

    switch (this->send_mode) {
        case kArwSendModeBfc:
            if (kArwSendModeSpiShort == next_mode) {
                op = ArwSendModeOperation;
            } else {  //* kArwSendModeSpiLong
                this->err_code = kArwErrSendMode;
                return 1;
            }
            break;
        case kArwSendModeSpiLong:
            if (kArwSendModeBfc == next_mode) {
                this->err_code = kArwErrSendMode;
                return 1;
            } else {  //* kArwSendModeSpiShort
                op = ArwSpiLongToShort;
            }
            break;
        case kArwSendModeSpiShort:
            if (kArwSendModeSpiLong == next_mode) {
                op = ArwSpiShortToLong;
            } else {  //* kArwSendModeBfc
                op = ArwSendModeOperation;
            }
        default:
            break;
    }

    if (op(this)) {
        return 1;
    }

    this->send_mode = next_mode;
    return 0;
}

#if ARW_MALLOC_ENABLE
ArwHandle_t* ARW97420_Init(uint8_t device_num, ArwHardware_t* hw_ptr) {
#if ____has_include("FreeRTOS.h")
    ArwHandle_t* this = (ArwHandle_t*)pvPortMalloc(sizeof(ArwHandle_t));
#else
    ArwHandle_t* this = (ArwHandle_t*)malloc(sizeof(ArwHandle_t));
#endif
    this->device_num = device_num;
    this->hardware = *hw_ptr;
    this->chip_mode = kArwChipModeLoad;
    this->send_mode = kArwSendModeBfc;
    this->err_code = kArwOk;

    //* 上电初始化
    if (ArwInitWorkFlow(this)) {
#if __has_include("FreeRTOS.h")
        vPortFree(this);
#else
        free(this);
#endif
        return NULL;
    }
    return this;
}

void ARW97420_Deinit(ArwHandle_t* this) {
#if ARW_FREERTOS_ENABLE
    vPortFree(this);
#else
    free(this);
#endif
}
#else
uint8_t ARW97420_Init(ArwHandle_t* this) {
    ARW_CHECK_NULLPTR(this);

    this->chip_mode = kArwChipModeLoad;
    this->send_mode = kArwSendModeBfc;
    this->err_code = kArwOk;

    return ArwInitWorkFlow(this);
}
#endif

void ARW97420_LogError(ArwHandle_t* this) {
#define X_ARW_ERROR(code, msg) #msg,
    const char* err_msg[] = {X_ARW_ERROR_LIST};
#undef X_ARW_ERROR
    ARW_PRINTF("Error: %s.\n", err_msg[this->err_code]);
}
